{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程池资源管理优化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 资源泄漏风险：使用裸指针(`std::vector<Thread*>`)时，若未手动delete会导致内存泄漏，因为`vector`析构时不会自动释放指针指向的内存\n",
    "- 智能指针解决方案：将线程列表改为`std::vector<std::unique_ptr<Thread>>`，利用智能指针自动管理内存生命周期\n",
    "- 析构机制：\n",
    "  - `unique_ptr`会在`vector`析构时自动调用其析构函数\n",
    "  - `unique_ptr`的析构会释放其管理的堆内存对象\n",
    "  - 无需手动编写`delete`逻辑，符合现代C++资源管理规范"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 开发环境配置"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- C++标准设置：\n",
    "  - 默认使用C++14标准（支持`make_unique`等特性）\n",
    "  - 建议选择\"最新C++工作草案\"以兼容C++17/20特性\n",
    "- 跨平台编译注意：\n",
    "  - Linux下需添加编译选项：`-std=c++11/14/17`\n",
    "  - 编译器会提示不支持的语法特性\n",
    "- 版本特性差异：\n",
    "  - `make_shared`：C++11引入\n",
    "  - `make_unique`：C++14引入\n",
    "  - 需注意不同版本标准支持的特性差异"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 智能指针实践应用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 实现方式：\n",
    "  - 使用`std::make_unique`创建线程对象（C++14特性）\n",
    "  - 可简写为`auto ptr = std::make_unique<Thread>(...)`\n",
    "- 代码修改要点：\n",
    "  - 原裸指针需改为`unique_ptr`类型\n",
    "  - 构造函数参数直接传递给`make_unique`\n",
    "  - 自动内存管理，无需显式`new/delete`\n",
    "- 优势：\n",
    "  - 避免手动资源释放\n",
    "  - 保证异常安全\n",
    "  - 明确所有权语义"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程池初始化实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 线程创建流程：\n",
    "  - 确定初始线程数量`initThreadSize_`\n",
    "  - 循环创建线程对象：\n",
    "    - 使用`std::bind`绑定线程函数`threadFunc`\n",
    "    - 通过`make_unique`创建线程智能指针\n",
    "    - 将线程对象存入`threads_`容器\n",
    "  - 启动所有工作线程\n",
    "- 关键实现：\n",
    "  - 线程函数通过成员函数指针绑定\n",
    "  - this指针传递保持上下文\n",
    "  - 统一使用智能指针管理线程对象生命周期"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程池接口设计"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 核心接口：\n",
    "  - `submitTask`：提交任务到线程池\n",
    "  - `setTaskQueMaxThreshHold`：设置任务队列阈值\n",
    "  - `start`：启动线程池（默认4个工作线程）\n",
    "- 线程安全机制：\n",
    "  - `taskQueMtx_`：保护任务队列的互斥锁\n",
    "  - `notFull_/notEmpty_`：条件变量控制队列状态\n",
    "- 设计规范：\n",
    "  - 禁用拷贝构造和赋值操作（`=delete`）\n",
    "  - 使用`atomic_int`保证`taskSize_`的原子性\n",
    "  - 通过`PoolMode`枚举区分工作模式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# unique_ptr使用示例"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "unique_ptr的特性\n",
    "\n",
    "- 禁止拷贝特性：`unique_ptr`删除了左值引用的拷贝构造函数和赋值运算符，这是其\"唯一性\"的核心特性，确保资源只能被一个智能指针管理。\n",
    "- 移动语义支持：虽然禁止普通拷贝，但提供了右值引用参数的拷贝构造和赋值重载，支持通过`std::move`进行资源转移。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程池中的实际应用\n",
    "\n",
    "- 容器存储问题：当尝试将`unique_ptr`存入`std::vector`时，容器内部会尝试拷贝构造，触发编译错误\"尝试引用已删除的函数\"。\n",
    "- 解决方案：使用`std::move`将临时创建的`unique_ptr`（第49行代码）转换为右值后存入容器（第50行代码修改后），实现资源所有权的转移而非拷贝。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实践意义\n",
    "\n",
    "- 错误诊断能力：通过编译器报错信息应能快速联想到`unique_ptr`的禁止拷贝特性，这是C++开发者必备的debug能力。\n",
    "- 面试能力培养：在实际项目中遇到问题快速反应的能力，与面试时快速解决问题的要求高度一致，需要通过项目实践不断锻炼。\n",
    "- 验证方法：通过线程ID输出验证线程池正确初始化，各线程函数正常执行（begin/end threadFunc成对出现）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# submitTask"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程池任务提交\n",
    "\n",
    "- 外部调用接口：用户通过线程池对象的`submitTask`方法提交任务，参数为智能指针指向的派生类任务对象\n",
    "- 多态实现：采用继承与多态思想，提供抽象基类`Task`，用户自定义任务需继承该基类\n",
    "- 任务队列管理：使用`std::queue<std::shared_ptr<Task>>`作为任务队列，保证线程安全"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任务对象智能指针\n",
    "\n",
    "- 参数类型：使用`std::shared_ptr<Task>`作为参数类型，确保任务对象生命周期管理\n",
    "- 派生类要求：用户自定义任务必须从`Task`基类继承并实现虚函数\n",
    "- 内存安全：智能指针自动管理内存，避免内存泄漏问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "获取锁与线程通信\n",
    "\n",
    "- 互斥锁必要性：生产者(提交任务)和消费者(执行任务)需互斥访问任务队列\n",
    "- 锁实现方式：使用`std::unique_lockstd::mutex`管理`taskQueMtx_`锁\n",
    "- 条件变量应用：通过`notFull/notEmpty`条件变量实现线程间通信"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任务队列上限\n",
    "\n",
    "- 阈值定义：默认任务队列上限`TASK_MAX_THRESHHOLD`为1024\n",
    "- 内存保护：防止无限制任务提交导致内存耗尽\n",
    "- 动态调整：可通过`setTaskQueMaxThreshHold`方法修改阈值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任务提交失败处理\n",
    "\n",
    "- 超时机制：任务提交最长阻塞时间不超过1秒\n",
    "- 降级策略：队列满时返回提交失败，保证服务可用性\n",
    "- 用户体验：类似电商抢购场景的\"服务正忙\"提示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "条件变量通知机制\n",
    "\n",
    "- 等待条件：`notFull_.wait`检查`taskQue_.size() < taskQueMaxThreshHold_`\n",
    "- 智能通知：任务入队后`notEmpty_.notify_all()`唤醒消费者线程\n",
    "- 锁管理：条件变量wait会自动释放锁，唤醒后重新获取"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "代码实现逻辑\n",
    "\n",
    "- 核心步骤：\n",
    "  - 获取互斥锁\n",
    "  - 等待队列有空余位置\n",
    "  - 任务入队并计数\n",
    "  - 通知消费者线程\n",
    "- 原子计数：使用`taskSize_++`记录任务数量，与队列`size`区分\n",
    "- 异常处理：考虑任务提交超时情况，避免永久阻塞"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 生产者-消费者模型：`submitTask`作为生产者，线程池工作线程作为消费者\n",
    "- 线程安全保证：通过互斥锁和条件变量确保队列操作安全\n",
    "- 资源限制：任务队列上限防止资源耗尽\n",
    "- 服务稳定性：超时机制和服务降级保证系统可用性"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
